#include <bits/stdc++.h>

#define eb emplace_back
#define ep emplace
#define fi first
#define se second
#define in read<int>()
#define lin read<ull>()
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

using ll = long long;
using ull = unsigned long long;
using pii = pair < int, int >;
using vec = vector < int >;
using veg = vector < pii >;

template < typename T > T read() {
	T x = 0; bool f = 0; char ch = getchar();
	while(!isdigit(ch)) f |= ch == '-', ch = getchar();
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}

template < typename T > void chkmax(T &x, const T &y) { x = x > y ? x : y; }
template < typename T > void chkmin(T &x, const T &y) { x = x < y ? x : y; }

const int N = 1010;

int n, m, u[N], nid[N];
ull c[N], tb[110];
vec G[N];

ll calc(int x, int v) { return 1ll * (v - u[x]) * (v - u[x]); }

void clear() { rep(i, 0, 63) tb[i] = 0; }

bool ins(ull val, int fl) {
	per(i, 63, 0)
		if(val >> i & 1ull) {
			if(tb[i]) val ^= tb[i];
			else if(fl) return tb[i] = val, true;
			else return true;
		}
	return false;
}

const ll inf = 0x3f3f3f3f3f3f3f3f;

namespace F { // max_flow
	const int N = 1010;
	const int M = N * N;
    int h[N], now[N], d[N], cnt = 1, S, T, tot;
    struct edge { ll v, w, nxt; } e[M << 1];
    inline void tlink(int x, int y, ll w) { e[++cnt] = (edge) { y, w, h[x] }; h[x] = cnt; }
    inline void link(int x, int y, ll w) { tlink(x, y, w); tlink(y, x, 0); }
    inline void setst(int s, int t) { S = s; T = t; }
	void init(int tot) { F :: tot = tot; rep(i, 0, tot) h[i] = 0; setst(0, tot); cnt = 1; } 
    queue < int > q;
    bool bfs() {
		while(q.size()) q.pop(); q.push(S); rep(i, 0, tot) d[i] = 0; d[S] = 1; now[S] = h[S];
		while(!q.empty()) {
			int x = q.front(); q.pop();
			for(int i = h[x], y; i; i = e[i].nxt)
				if(e[i].w && !d[y = e[i].v]) {
					d[y] = d[x] + 1; q.push(y); now[y] = h[y];
					if(y == T) return 1;
				}
		} return 0;
    }
    ll dinic(int x, ll flow) {
		if(x == T) return flow;
		ll res = flow;
		for(int i = now[x], y; i && res; i = e[i].nxt) {
			now[x] = i;
			if(e[i].w && d[y = e[i].v] == d[x] + 1) {
				ll k = dinic(y, min(res, e[i].w));
				if(!k) d[y] = 0; e[i].w -= k; e[i ^ 1].w += k; res -= k;
			}
		}
		return flow - res;
    }
    ll runit() {
		ll maxflow = 0, flow;
		while(bfs()) while(flow = dinic(S, inf)) maxflow += flow;
		return maxflow;
    }
}

int ans[N], p[N], q[N];

void divide(int l, int r, int lval, int rval) {
	if(l > r || lval == rval) { rep(i, l, r) ans[p[i]] = lval; return; }
	int mid = lval + rval >> 1, tot = 0;
	rep(i, l, r) nid[p[i]] = ++tot;
	F :: init(tot + 1);
	rep(i, l, r) {
		int x = p[i];
		for(auto y : G[x])
			if(nid[y]) F :: link(nid[y], nid[x], inf); 
	}
	rep(i, l, r) {
		ll t1 = calc(p[i], mid), t2 = calc(p[i], mid + 1), delta = t1 - t2;
		if(delta < 0) F :: link(0, nid[p[i]], -delta);
		else F :: link(nid[p[i]], tot + 1, +delta);
	}
	F :: runit(); //cerr << F :: cnt << endl;
	int cur = l, top = 0, tcur = 0;
	//rep(i, l, r) if(F :: d[nid[p[i]]] == 0) for(auto y : G[p[i]]) if(nid[y]) assert(F :: d[nid[y]] == 0);
	rep(i, l, r) { if(F :: d[nid[p[i]]] == 0) q[++top] = p[i]; else p[cur++] = p[i]; nid[p[i]] = 0; }
	tcur = cur; rep(i, 1, top) p[cur++] = q[i];
	//	cerr << l << " " << tcur << " " << r << " " << lval << " " << rval << " " << endl;
	divide(l, tcur - 1, lval, mid); divide(tcur, r, mid + 1, rval);
}

int a[N], b[N];

int main() {
#ifndef ONLINE_JUDGE
	freopen("shop3.in", "r", stdin);
#endif
	n = in, m = in; int mx = 0;
	rep(i, 1, n) c[i] = lin; rep(i, 1, n) u[i] = in, chkmax(mx, u[i]);
	rep(i, 1, m) a[i] = in; rep(i, 1, m) b[i] = in;
	rep(x, 1, m) {
		clear(); 
		rep(i, 1, m) { nid[a[i]] = 1; if(i != x) ins(c[a[i]], 1); }
		rep(i, 1, n) if(!nid[i] && ins(c[i], 0)) G[a[x]].eb(i);
		rep(i, 1, m) nid[a[i]] = 0;
	}
	rep(x, 1, m) {
		clear();
		rep(i, 1, m) { nid[b[i]] = 1; if(i != x) ins(c[b[i]], 1); }
		rep(i, 1, n) if(!nid[i] && ins(c[i], 0)) G[i].eb(b[x]);
		rep(i, 1, m) nid[b[i]] = 0;
	}
	//rep(x, 1, n) for(auto y : G[x]) cerr << x << " " << y << endl;
	//rep(x, 1, n) for(auto y : G[x]) cerr << x << " " << y << endl; 
	rep(i, 1, n) p[i] = i;
	divide(1, n, 0, mx); ll ans = 0; rep(i, 1, n) ans += calc(i, ::ans[i]);//, cerr << ::ans[i] << endl;
	printf("%lld\n", ans); return 0;
}
